local modeDynamic = 0
local modeStatic = 1
local mode = 0
local surfaceFloor = 0
local surfaceCeiling = 1
local surfaceType = 0
local replaceBlocks = true
local removeObstacles = true
local returnTurtle = true
local depth = 0
local width = 0
local currentSlot = 2
local fuelSlot = 1
local detectingSurfaceSize = "Detecting surface size"
local detectedSurfaceSize = "Detected surface size:"
local errorDepth = "Error detecting surface depth"
local errorWidth = "Error detecting surface width"
local invalidDepth = "Invalid surface depth"
local invalidWidth = "Invalid surface width"
local refuelingTurtle = "Low fuel detected, refueling"
local outOfFuel = "Turtle out of fuel, waiting for refuel"
local outOfMaterials = "Turtle ran out of materials"
local refillAndContinue = "Refill materials and press enter"
local obstacleEncountered = "Obstacle encountered, waiting"
local surfaceCompleted = "Surface laying completed"
local turtleReturning = "Turtle returning to start"
local turtleReturned = "Turtle returned to starting position"
local author = "Kevin Scroggins"
local nickname = "nitro glycerine"
local email = "nitro404@gmail.com
local website = "http://www.nitro404.com"

function checkFuel()
  if turtle.getItemCount(fuelSlot) == 0 then
    print(outOfFuel)
    
    while turtle.getItemCount(fuelSlot) == 0 do
      os.sleep(1)
    end
  end
  
  if turtle.getFuelLevel() < 15 then
    print(refuelingTurtle)
    turtle.select(fuelSlot)
    if turtle.refuel(1) ~= true then
      print(outOfFuel)
      
      while turtle.refuel(1) ~= true do
        os.sleep(1)
      end
    end
    
    checkFuel()
  end
end

function forward(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.forward() ~= true then
      print(obstacleEncountered)
      
      while turtle.forward() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.dig()
        end
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function back(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.back() ~= true then
      print(obstacleEncountered)
      
      while turtle.back() ~= true do
        checkFuel()
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function up(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.up() ~= true then
      print(obstacleEncountered)
      
      while turtle.up() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.digUp()
        end
        
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function down(d)
  if d == nil then
    d = 1
  elseif d < 1 then
    return
  end
  
  for i = 0, d - 1, 1 do
    checkFuel()
    
    if turtle.down() ~= true then
      print(obstacleEncountered)
      
      while turtle.down() ~= true do
        checkFuel()
        
        if removeObstacles == true then
          turtle.digDown()
        end
        os.sleep(0.5)
      end
    end
  end
  
  checkFuel()
end

function left(n)
  if n == nil then
    n = 1
  elseif n < 1 then
    return
  end
  
  for i = 0, n - 1, 1 do
    turtle.turnLeft()
  end
end

function right(n)
  if n == nil then
    n = 1
  elseif n < 1 then
    return
  end
  
  for i = 0, n - 1, 1 do
    turtle.turnRight()
  end
end

function checkDistance()
  local d = 1
  
  checkFuel()
  
  while turtle.forward() do
    checkFuel()
    
    d = d + 1
  end
  
  for i = 0, d - 2, 1 do
    back()
  end
  
  return d
end

function checkDimensions()
  print(detectingSurfaceSize)
  
  depth = checkDistance()
  turtle.turnRight()
  
  if depth < 1 then
    print(errorDepth)
    return false
  end
  
  width = checkDistance()
  turtle.turnLeft()
  
  if width < 1 then
    print(errorWidth)
    return false
  end
  
  return true
end

function hasMaterials()
  for i = 2, 16, 1 do
    if turtle.getItemCount(i) ~= 0 then
      return i
    end
  end
  return -1
end

function checkMaterials()
  while turtle.getItemCount(currentSlot) == 0 do
   if currentSlot == 16 then
     currentSlot = hasMaterials()
     
     while currentSlot < 2 do
       print(outOfMaterials)
       print(refillAndContinue)
       
       io.read()
       
       currentSlot = hasMaterials()
     end
   else
     currentSlot = currentSlot + 1
   end
  end
end

function placeBlock()
  checkMaterials()
  
  if replaceBlocks == true then
    if surfaceType == surfaceFloor then
      if turtle.detectDown() == true then
	    turtle.digDown()
	  end
	elseif surfaceType == surfaceCeiling then
	  if turtle.detectUp() == true then
	    turtle.digUp()
	  end
	end
  end
  
  turtle.select(currentSlot)
  
  if surfaceType == surfaceFloor then
    turtle.placeDown()
  elseif surfaceType == surfaceCeiling then
    turtle.placeUp()
  end
end

function laySurface()
  local direction = 0
  
  if mode == modeDynamic then
    if checkDimensions() ~= true then
      return false
    end
  end
  
  if depth < 1 then
    print(invalidDepth)
    return false
  end
  
  if width < 1 then
    print(invalidWidth)
    return false
  end
  
  print("Laying surface with dimensions:")
  write("Width: ")
  write(width)
  write("\n")
  write("Depth: ")
  write(depth)
  write("\n")
  
  for i = 0, width - 1, 1 do
    for j = 0, depth - 1, 1 do
      placeBlock()
      
      if j < depth - 1 then
        forward()
      end
    end
    
    if i < width - 1 then
      if direction == 0 then
        turtle.turnRight()
      else
        turtle.turnLeft()
      end
      
      forward()
      
      if direction == 0 then
        turtle.turnRight()
        direction = 1
      else
        turtle.turnLeft()
        direction = 0
      end
    end
  end
  
  print(surfaceCompleted)
  
  if returnTurtle == true then
    print(turtleReturning)
    
    if direction == 0 then
      turtle.turnRight()
      turtle.turnRight()
      
      for i = 0, depth - 2, 1 do
        forward()
      end
    end
    
    turtle.turnRight()
    
    for i = 0, width - 2, 1 do
      forward()
    end
    
    turtle.turnRight()
    
    print(turtleReturned)
  end
    
  return true
end

laySurface()
